home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / VELENG10.ZIP / CONNECT4.C < prev    next >
C/C++ Source or Header  |  1997-07-27  |  8KB  |  332 lines

  1. // ****************************************************************************
  2. // *                                                                          *
  3. // *                      Velena Source Code V1.0                             *
  4. // *                   Written by Giuliano Bertoletti                         *
  5. // *       Based on the knowledged approach of Louis Victor Allis             *
  6. // *   Copyright (C) 1996-97 by Giuliano Bertoletti & GBE 32241 Software PR   *
  7. // *                                                                          *
  8. // ****************************************************************************
  9.  
  10. // Portable engine version.
  11. // read the README file for further informations.
  12.  
  13. // ==========================================================================
  14.  
  15. // This module contains the main function. Just see file cmdline.c to see how
  16. // to send positions to the engine. 
  17.  
  18. // Main module
  19.  
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include <stdlib.h>
  23. #include <malloc.h>
  24.  
  25. #include <sys/types.h>
  26. #include <sys/stat.h>
  27. #include <fcntl.h>
  28.  
  29. #include <unistd.h>
  30.  
  31. #include "connect4.h"
  32. #include "pnsearch.h"
  33. #include "proto.h"
  34.  
  35. #define BLKSIZE 16384           // Buffer size for I/O
  36.  
  37. #define PLAYER1 0
  38. #define PLAYER2 1
  39.  
  40. struct board *brd;
  41.  
  42. short check_solution_groups(struct board *board)
  43.     {
  44.     short x,y,z,q,c,answer=YES;
  45.  
  46.     for(y=0;y<BOARDY && answer;y++)
  47.         for(x=0;x<BOARDX && answer;x++)
  48.             for(z=0;z<board->solvable_groups->sqpnt[ELM(x,y)] && answer;z++)
  49.                 {
  50.                 answer=NO;
  51.                 c=board->solvable_groups->square[ELM(x,y)][z];
  52.                 for(q=0;q<TILES;q++)
  53.                     if(*board->groups[c][q]==ELM(x,y)) answer=YES;
  54.                 }
  55.  
  56.     return answer;
  57.     }
  58.  
  59.  
  60. // Initialize the program data structures, it reads and builds (if needed)
  61. // the opening book.
  62.  
  63. void init_prg(struct board *board)
  64.     {
  65.     long size,len;
  66.     FILE *h1;
  67.     short x;
  68.  
  69.     brd=board;
  70.  
  71.     board->wins[PLAYER1]=0;
  72.     board->wins[PLAYER2]=0;
  73.     board->draws        =0;
  74.     board->lastguess    =0;
  75.     board->bestguess   =MAXMEN;
  76.     board->lastwin       =EMPTY;
  77.  
  78.     board->white_lev=0;   // Human
  79.     board->black_lev=3;   // Computer-Strong
  80.  
  81.     board->videotype = CHARS;
  82.     board->enablegr  = NO;
  83.  
  84.     board->autotest = NO;
  85.  
  86.     for(x=0;x<3;x++)
  87.     board->rule[x]=0L;
  88.  
  89.     board->oracle_guesses=0;
  90.  
  91.     h1=fopen(WHITE_BOOK,"rb");
  92.     if(!h1) fatal_error("Opening book not present");
  93.  
  94.     size=fileln(h1);
  95.     if(size%14!=0) fatal_error("White opening book is corrupted");
  96.  
  97.     board->wbposit=size/14;
  98.  
  99.     board->white_book=(unsigned char *)malloc(size);
  100.     if(!board->white_book) fatal_error("Not enough memory to allocate opening book");
  101.  
  102.     len=0;               // We read all the position from disk
  103.     while(size>0)     // each position takes 14 bytes of storage
  104.         {
  105.         fread(&board->white_book[len],1,14,h1);
  106.         len+=14;
  107.         size-=14;
  108.         }
  109.  
  110.     fclose(h1);
  111.  
  112.     board->bbposit=0;
  113.     }
  114.  
  115. void initboard(struct board *board)
  116.     {
  117.     short x,y,i,j,p;
  118.  
  119.     randomize();
  120.  
  121.     for(i=0;i<10;i++)
  122.         board->instances[i]=0L;
  123.  
  124.     /* Groups initializations */
  125.  
  126.     // Step one. Horizontal lines.
  127.  
  128.     i=0;
  129.     for(y=0;y<BOARDY;y++)
  130.         for(x=0;x<BOARDX-3;x++)
  131.             {
  132.             board->groups[i][0]=&board->square[ELM(x+0,y)];
  133.             board->groups[i][1]=&board->square[ELM(x+1,y)];
  134.             board->groups[i][2]=&board->square[ELM(x+2,y)];
  135.             board->groups[i][3]=&board->square[ELM(x+3,y)];
  136.  
  137.             board->xplace[i][0]=x;
  138.             board->xplace[i][1]=x+1;
  139.             board->xplace[i][2]=x+2;
  140.             board->xplace[i][3]=x+3;
  141.  
  142.             board->yplace[i][0]=y;
  143.             board->yplace[i][1]=y;
  144.             board->yplace[i][2]=y;
  145.             board->yplace[i][3]=y;
  146.  
  147.             i++;
  148.             }
  149.  
  150.     // Step two. Vertical lines
  151.  
  152.     for(y=0;y<BOARDY-3;y++)
  153.         for(x=0;x<BOARDX;x++)
  154.             {
  155.             board->groups[i][0]=&board->square[ELM(x,y+0)];
  156.             board->groups[i][1]=&board->square[ELM(x,y+1)];
  157.             board->groups[i][2]=&board->square[ELM(x,y+2)];
  158.             board->groups[i][3]=&board->square[ELM(x,y+3)];
  159.  
  160.             board->xplace[i][0]=x;
  161.             board->xplace[i][1]=x;
  162.             board->xplace[i][2]=x;
  163.             board->xplace[i][3]=x;
  164.  
  165.             board->yplace[i][0]=y+0;
  166.             board->yplace[i][1]=y+1;
  167.             board->yplace[i][2]=y+2;
  168.             board->yplace[i][3]=y+3;
  169.  
  170.             i++;
  171.             }
  172.  
  173.     // Step three. Diagonal (north east) lines
  174.  
  175.     for(y=0;y<BOARDY-3;y++)
  176.         for(x=0;x<BOARDX-3;x++)
  177.             {
  178.             board->groups[i][0]=&board->square[ELM(x+0,y+0)];
  179.             board->groups[i][1]=&board->square[ELM(x+1,y+1)];
  180.             board->groups[i][2]=&board->square[ELM(x+2,y+2)];
  181.             board->groups[i][3]=&board->square[ELM(x+3,y+3)];
  182.  
  183.             board->xplace[i][0]=x+0;
  184.             board->xplace[i][1]=x+1;
  185.             board->xplace[i][2]=x+2;
  186.             board->xplace[i][3]=x+3;
  187.  
  188.             board->yplace[i][0]=y+0;
  189.             board->yplace[i][1]=y+1;
  190.             board->yplace[i][2]=y+2;
  191.             board->yplace[i][3]=y+3;
  192.  
  193.             i++;
  194.             }
  195.  
  196.     // Step four. Diagonal (south east) lines
  197.  
  198.     for(y=3;y<BOARDY;y++)
  199.         for(x=0;x<BOARDX-3;x++)
  200.             {
  201.             board->groups[i][0]=&board->square[ELM(x+0,y-0)];
  202.             board->groups[i][1]=&board->square[ELM(x+1,y-1)];
  203.             board->groups[i][2]=&board->square[ELM(x+2,y-2)];
  204.             board->groups[i][3]=&board->square[ELM(x+3,y-3)];
  205.  
  206.             board->xplace[i][0]=x+0;
  207.             board->xplace[i][1]=x+1;
  208.             board->xplace[i][2]=x+2;
  209.             board->xplace[i][3]=x+3;
  210.  
  211.             board->yplace[i][0]=y-0;
  212.             board->yplace[i][1]=y-1;
  213.             board->yplace[i][2]=y-2;
  214.             board->yplace[i][3]=y-3;
  215.  
  216.             i++;
  217.             }
  218.  
  219.     if(i!=GROUPS) fatal_error("Implementation error!");
  220.  
  221.     for(x=0;x<64;x++)
  222.         {
  223.         board->solvable_groups->sqpnt[x]=0;
  224.         for(y=0;y<16;y++)
  225.             board->solvable_groups->square[x][y]=-1;
  226.         }
  227.  
  228.     for(x=0;x<BOARDX;x++)
  229.         for(y=0;y<BOARDY;y++)
  230.             board->square[ELM(x,y)]=ELM(x,y);
  231.  
  232.  
  233.     for(i=0;i<GROUPS;i++)
  234.         for(j=0;j<TILES;j++)
  235.             {
  236.             p=*board->groups[i][j];
  237.             board->solvable_groups->square[p][board->solvable_groups->sqpnt[p]++]=i;
  238.             }
  239.  
  240.     if(!check_solution_groups(board))
  241.         fatal_error("Implementation error!");
  242.  
  243.     // Here we set all out squares to a default value to detect problems
  244.  
  245.     for(i=0;i<8;i++)
  246.         {
  247.         board->square[ELM(7,i)]=FULL;
  248.         board->square[ELM(i,6)]=board->square[ELM(i,7)]=FULL;
  249.         }
  250.  
  251.     board->stack[7]=FULL;
  252.  
  253.     for(y=0;y<BOARDY;y++)
  254.         for(x=0;x<BOARDX;x++)
  255.             board->square[ELM(x,y)]=EMPTY;
  256.  
  257.     for(x=0;x<BOARDX;x++)
  258.         board->stack[x]=0;
  259.  
  260.     board->turn=WHITE;
  261.     board->filled=0;
  262.         board->cpu=0x01;
  263.         return;
  264.     }
  265.  
  266. void initTitle()
  267.     {
  268.     printf("\n");
  269.     printf("Velena Engine %s; revision %s\n",SEARCH_ENGINE_VERSION,__DATE__);
  270.     
  271.     printf("\n");
  272.     printf("Connect four AI engine written by Giuliano Bertoletti\n");
  273.     printf("Based on the knowledged approach of Victor Allis\n");
  274.     printf("Copyright (C) 1996-97 Giuliano Bertoletti ");
  275.     printf("and GBE 32241 Software PR.\n");
  276.     printf("All rights reserved.\n\n");
  277.     }
  278.  
  279. void main(short ac,char **av)
  280.     {
  281.     short x;
  282.     struct board *board;
  283.  
  284.         // Here we initialize our environment and the call
  285.         // command_line_input in file cmdline.c to process data from the
  286.         // outside world.
  287.  
  288.     initTitle();
  289.     
  290.         fight(NO);
  291.  
  292.     brd=NULL;
  293.     board=(struct board *)malloc(sizeof(struct board));
  294.     board->solvable_groups=(struct solvable_groups *)
  295.                             malloc(sizeof(struct solvable_groups));
  296.  
  297.     if(!board || !board->solvable_groups)
  298.         fatal_error("Cannot allocate memory!");
  299.  
  300.         board->debug=0;
  301.  
  302.         init_prg(board);       // Initialize data structures
  303.  
  304.     for(x=0;x<ALLOC_SOLUTIONS;x++)
  305.         {
  306.         board->solution[x]=(struct solution *)
  307.                            malloc(sizeof(struct solution));
  308.         if(!board->solution[x]) 
  309.              fatal_error("Not enough memory for solutions");
  310.         }
  311.  
  312.         board->usegraphics = NO;
  313.  
  314.         // ******************************************************************
  315.  
  316.         // Build your program here...
  317.  
  318.         command_line_input(board);
  319.  
  320.         // ******************************************************************
  321.  
  322.         for(x=0;x<ALLOC_SOLUTIONS;x++)
  323.         if(board->solution[x]) free(board->solution[x]);
  324.  
  325.         free(board->solvable_groups);
  326.         free(board);
  327.         exit(0);
  328.         }
  329.  
  330.  
  331.  
  332.